package com.meta.platform.sms.service.impl;

import com.meta.framework.common.utils.spring.SpringUtils;
import com.meta.platform.sms.constants.SendStatus;
import com.meta.platform.sms.domain.SmsConfig;
import com.meta.platform.sms.domain.SmsMobileBlackList;
import com.meta.platform.sms.domain.SmsSendRecord;
import com.meta.platform.sms.mapper.SmsConfigMapper;
import com.meta.platform.sms.mapper.SmsMobileBlackListMapper;
import com.meta.platform.sms.mapper.SmsSendRecordMapper;
import com.meta.platform.sms.request.InvokeThirdSmsParam;
import com.meta.platform.sms.request.SendSmsParam;
import com.meta.platform.sms.service.InnerSendSmsService;
import com.meta.platform.sms.service.invoke.InvokeThirdSmsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@Slf4j
public class InnerSendSmsServiceImpl implements InnerSendSmsService {
    @Resource
    private SmsConfigMapper smsConfigMapper;

    @Resource
    private SmsMobileBlackListMapper smsMobileBlackListMapper;

    @Resource
    private SmsSendRecordMapper smsSendRecordMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void sendSms(SendSmsParam sendSmsParam) {
        SmsConfig smsConfig = smsConfigMapper.querySmsInfoBySmsKey(sendSmsParam.getSmsKey());
        if (smsConfig == null) {
            return;
        }

        List<String> sendMobiles = sendSmsParam.getMobiles();
        List<SmsMobileBlackList> smsMobileBlackLists = smsMobileBlackListMapper.batchQueryByMobileList(sendSmsParam.getMobiles());
        if (!CollectionUtils.isEmpty(smsMobileBlackLists)) {
            Set<String> blackMobiles = smsMobileBlackLists.stream().map(SmsMobileBlackList::getMobile).collect(Collectors.toSet());
            Iterator<String> iterator = sendMobiles.iterator();
            do {
                String mobile = iterator.next();
                if (blackMobiles.contains(mobile)) {
                    iterator.remove();
                }
            } while (iterator.hasNext());

            sendSmsParam.setMobiles(sendMobiles);
        }

        if (!CollectionUtils.isEmpty(sendMobiles)) {
            InvokeThirdSmsService invokeThirdSmsService = SpringUtils.getBean(smsConfig.getOuterSmsChannel());
            InvokeThirdSmsParam invokeThirdSmsParam = invokeThirdSmsService.generateInvokeParam(smsConfig, sendSmsParam);
            Boolean invokeResult = invokeThirdSmsService.invokeThirdSmsService(invokeThirdSmsParam);

            List<SmsSendRecord> records = new ArrayList<>();
            for (String sendMobile : sendMobiles) {
                SmsSendRecord sendRecord = new SmsSendRecord();
                sendRecord.setBizId(invokeThirdSmsParam.getBizId());
                sendRecord.setInnerSmsKey(smsConfig.getInnerSmsKey());
                sendRecord.setSendMobile(sendMobile);
                sendRecord.setSmsContent(invokeThirdSmsParam.getFinalSmsContent());
                sendRecord.setOuterSmsChannel(smsConfig.getOuterSmsChannel());
                sendRecord.setOuterSmsTemplateCode(smsConfig.getOuterSmsTemplateCode());
                sendRecord.setSendTime(new Date());
                sendRecord.setSendStatus(invokeResult ? SendStatus.SENDING.getStatus() : SendStatus.INVOKE_FAILED.getStatus());
                sendRecord.setResendCount(0);
                records.add(sendRecord);
            }

            if (!CollectionUtils.isEmpty(records)) {
                smsSendRecordMapper.batchInsertSmsRecord(records);
            }
        }
    }

    @Override
    public void resendSms() {

    }
}
